﻿/*
* 作者:haojielyb
* 邮箱:haojielyb@qq.com
*/

using Haojielyb.Swagger2md.Middleware;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Haojielyb.Swagger2md.Extensions
{
    /// <summary>
    /// <see cref="ISwagger2mdGenerator"/>服务
    /// </summary>
    public static class SwaggerDocGeneratorExtension
    {
        /// <summary>
        /// 注册<see cref="ISwagger2mdGenerator"/>服务
        /// </summary>
        /// <param name="services"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public static IServiceCollection AddSwagger2md(this IServiceCollection services, Func<Options> opt)
        {
            System.Console.WriteLine("注册 SwaggerGenerator ");
            services.AddScoped<SwaggerGenerator>();
            services.AddScoped<ISwagger2mdGenerator, Swagger2mdGenerator>();
            services.AddScoped<Options>((f) =>
            {
                return opt();
            });

            services.AddScoped<Swagger2mdMiddleware>();
            return services;
        }

        /// <summary>
        /// 注册<see cref="ISwagger2mdGenerator"/>服务
        /// </summary>
        /// <param name="services"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public static IServiceCollection AddSwagger2md(this IServiceCollection services, Action<Options> opt)
        {
            System.Console.WriteLine("注册 SwaggerGenerator ");
            services.AddScoped<SwaggerGenerator>();
            services.AddScoped<ISwagger2mdGenerator, Swagger2mdGenerator>();
            services.AddScoped<Options>((f) =>
            {
                Options _opt = new Options();
                opt(_opt);
                return _opt;
            });

            services.AddScoped<Swagger2mdMiddleware>();
            return services;
        }

        /// <summary>
        /// 注册<see cref="ISwagger2mdGenerator"/>服务
        /// </summary>
        /// <param name="services"></param>
        /// <param name="opt"></param>
        /// <returns></returns>

        public static IServiceCollection AddSwagger2md(this IServiceCollection services)
        {
            System.Console.WriteLine("注册 SwaggerGenerator ");
            services.AddScoped<SwaggerGenerator>();
            services.AddScoped<ISwagger2mdGenerator, Swagger2mdGenerator>();
            services.AddScoped<Options>(f => new Options());

            services.AddScoped<Swagger2mdMiddleware>();
            return services;
        }

        /// <summary>
        /// 注册<see cref="ISwagger2mdGenerator"/>服务
        /// </summary>
        /// <param name="services"></param>
        /// <param name="opt"></param>
        /// <returns></returns>

        public static IServiceCollection AddSwagger2md(this IServiceCollection services, String name)
        {
            System.Console.WriteLine("注册 SwaggerGenerator ");
            services.AddScoped<SwaggerGenerator>();
            services.AddScoped<ISwagger2mdGenerator, Swagger2mdGenerator>();
            services.AddScoped<Options>(f => new Options { name = name });

            services.AddScoped<Swagger2mdMiddleware>();
            return services;
        }

        /// <summary>
        /// 判断是否为 Object 类型
        /// </summary>
        /// <param name="openApiSchema"></param>
        /// <returns></returns>
        public static bool IsObject(this OpenApiSchema openApiSchema, IDictionary<string, OpenApiSchema> schemas)
        {
            return openApiSchema.Type == null && openApiSchema.Reference != null && schemas.FirstOrDefault(x => x.Key == openApiSchema.Reference.Id).Value.Enum.Count == 0;
        }

        /// <summary>
        /// 判断是否为枚举类型
        /// </summary>
        /// <param name="openApiSchema"></param>
        /// <param name="schemas"></param>
        /// <returns></returns>
        public static bool IsEnum(this OpenApiSchema openApiSchema, IDictionary<string, OpenApiSchema> schemas)
        {
            return openApiSchema.Reference != null && schemas.FirstOrDefault(x => x.Key == openApiSchema.Reference.Id).Value.Enum.Count != 0;
        }

        /// <summary>
        /// 判断是否为数组类型
        /// </summary>
        /// <param name="openApiSchema"></param>
        /// <returns></returns>
        public static bool IsArray(this OpenApiSchema openApiSchema)
        {
            return openApiSchema.Type == "array" && openApiSchema.Items != null;
        }

        /// <summary>
        /// 判断是否为基础数组类型
        /// </summary>
        /// <param name="openApiSchema"></param>
        /// <returns></returns>
        public static bool IsBaseTypeArray(this OpenApiSchema openApiSchema)
        {
            return openApiSchema.Type == "array" && openApiSchema.Items != null && openApiSchema.Items.Type != null && openApiSchema.Items.Reference == null;
        }

        /// <summary>
        /// 判断是否为基本类型
        /// </summary>
        /// <param name="openApiSchema"></param>
        public static bool IsBaseType(this OpenApiSchema openApiSchema)
        {
            return openApiSchema.Type != null;
        }
    }
}